import axios, { AxiosError } from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import type { MyResponseType, Params } from '@/types'
import { config } from '@/config'
import { useAppStore } from '@/stores/app'

const { baseURL, timeout } = config

/**
 * http
 */
class Request {
  instance: AxiosInstance

  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
    this.interceptors()
  }

  // 拦截器
  interceptors() {
    this.instance.interceptors.request.use(this.onRequest, this.onRequestError)
    this.instance.interceptors.response.use(this.onResponse, this.onResponseError)
  }

  onRequest(config: AxiosRequestConfig): AxiosRequestConfig {
    const store = useAppStore()
    if (store.token) {
      config.headers!.Authorization = `Bearer ${store.token}`
    }
    return config
  }

  onRequestError(error: AxiosError): Promise<AxiosError> {
    return Promise.reject(error)
  }

  onResponse(response: AxiosResponse): AxiosResponse {
    return response.data
  }

  onResponseError(error: AxiosError): Promise<AxiosError> {
    return Promise.reject(error)
  }

  // methods
  request<T>(config: AxiosRequestConfig): Promise<T> {
    return this.instance.request<any, T>(config)
  }

  /**
   * 通用的post请求方法
   * @param url 请求地址
   * @param params 参数
   * @returns 请求结果
   */
  async post<T, P>(url: string, params: P): Promise<T> {
    const resp = await this.instance.post<T, MyResponseType<T>>(url, params)
    return resp.data
  }

  /**
   * 查询专用，传递框架约定的查询条件格式
   * @param url 请求地址
   * @param params 查询参数
   * @returns 查询结果
   */

  async query<T>(url: string, params: Params): Promise<T> {
    const resp = await this.instance.post<T, MyResponseType<T>>(url, params)
    return resp.data
  }
}

// exports

export const request = new Request({
  baseURL,
  timeout
})

export const http = axios.create({
  baseURL,
  timeout
})
